<template>
  <g
    :class="`workflow-group-node ${isSelected ? 'selected' : ''} ${isDragging ? 'dragging' : ''} ${isResizing ? 'resizing' : ''}`"
    :transform="`translate(${group.position.x + 2 },${group.position.y + 2})`"
    :id="`node-${group.id}`"
  >
  
  
    <!-- 选中状态的调整边框 - 最底层渲染"-->
    <template v-if="isSelected">
      <rect
        class="resize-border"
        x="-4"
        y="-4"
        :width="currentWidth + 8"
        :height="group.size.height + 8"
        fill="none"
        stroke="#409EFF"
        stroke-width="2"
        stroke-dasharray="4 4"
        @mousedown="handleResizeBorderMouseDown"
        @mousemove="handleResizeBorderMouseMove"
      />
    </template>

    <!-- 主体区域 -->
    <g >
      <rect
        class="group-background"
        :width="currentWidth"
        :height="group.size.height"
        fill="rgba(40, 44, 52, 0.5)"
        :stroke="isSelected ? '#409EFF' : '#666'"
        stroke-width="1"
        rx="4"
        x="-2"
        y="-2"
      />
    </g>
    
	
    <!-- 标题栏 -->
    <g 
      class="group-header"
      :id="`${group.id}_head`"
      :style="{ zIndex: isDragging ? 1000 : 1 }"
    >
      <defs>
        <linearGradient :id="`headerGradient-${group.id}`" x1="0%" y1="0%" x2="100%" y2="0%">
          <stop offset="0%" stop-color="#666" />
          <stop offset="100%" stop-color="#888" />
        </linearGradient>
      </defs>
	  
	  <path
		@mousedown="handleDragStart"
	    :d="`M0,4 A4,4 0 0,1 4,0 H${currentWidth - 8} A4,4 0 0,1 ${currentWidth-4},4 V30 H0 Z`"
	    :fill="`url(#headerGradient-${group.id})`"
	  />
	  
	  <text
	    x="10"
	    y="16"
	    text-anchor="start"
	    dominant-baseline="middle"
	    fill="#fff"
	    font-size="16px"
	    user-select="none"
	    style="paint-order: stroke;"
	    shape-rendering="geometricPrecision"
	    text-rendering="geometricPrecision"
		pointer-events="painted"
	    @click.stop="handleRename"
	  >{{ group.title }}</text>
	  
    </g>
  </g>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import type { WorkflowGroup, Connection } from '@/stores/workflow';
import type { Position } from '@/views/data-manage/workflow/components/types';
import { useWorkflowStore } from '@/stores/workflow';

// Props 定义
interface Props {
  group: WorkflowGroup;
  selected?: boolean;
  svgContainer: SVGSVGElement;
}

const props = defineProps<Props>();

// Emits 定义
const emit = defineEmits<{
  (e: 'select', groupId: string): void;
  // (e: 'update:position', groupId: string, position: Position): void;
  // (e: 'update:size', groupId: string, size: { width: number; height: number }): void;
}>();

const isDragging = ref(false);
const dragOffset = reactive({ x: 0, y: 0 });
const dragStartPos = ref({ x: 0, y: 0 });

let scale: number;
const workflowStore = useWorkflowStore();

// 计算属性：是否被选中
const isSelected = computed(() => {
  return workflowStore.state.selectedGroupIds.includes(props.group.id);
});

const handleClick = () => {
  emit('select', props.group.id);
};

// 添加状态存储包含节点的初始位置
const containedNodesInitialPositions = ref<Map<string, Position>>(new Map());
const containedGroupsInitialPositions = ref<Map<string, Position>>(new Map());

// 添加状态存储受影响的节点和连接线
const affectedNodeIds = ref<Set<string>>(new Set());
const affectedConnections = ref<Connection[]>([]);

// 添加一个判断节点是否完全在组内的函数
const isNodeFullyContained = (node: any, group: any) => {
  // 获取节点的边界
  const nodeLeft = node.position.x;
  const nodeRight = node.position.x + (node.size?.width || 0);
  const nodeTop = node.position.y;
  const nodeBottom = node.position.y + (node.size?.height || 0);
  
  // 获取组的边界
  const groupLeft = group.position.x;
  const groupRight = group.position.x + group.size.width;
  const groupTop = group.position.y;
  const groupBottom = group.position.y + group.size.height;
  
  // 检查节点是否完全在组内
  return nodeLeft >= groupLeft &&
         nodeRight <= groupRight &&
         nodeTop >= groupTop &&
         nodeBottom <= groupBottom;
};

const handleDragStart = (e: MouseEvent) => {
  if (e.button !== 0) return;
  if ((e.target as Element).classList.contains('resize-border')) return;
  
  e.preventDefault();
  e.stopPropagation();
  
  handleClick();
  
  if(!props.svgContainer) return;
  const svg = props.svgContainer;
  if (!svg) return;
  
  const _data = workflowStore.getSvgTransform(svg);
  if(!_data)  return;
  scale = _data.scale;
  
 // const svgRect = svg.getBoundingClientRect();
  
  dragOffset.x = props.group.position.x;
  dragOffset.y = props.group.position.y;
  
  dragStartPos.value = {
    x: e.clientX,
    y: e.clientY
  };
  
  // 清理之前的记录
  containedNodesInitialPositions.value.clear();
  containedGroupsInitialPositions.value.clear();
  affectedNodeIds.value.clear();
  
  // 修改记录节点位置的部分
  props.group.nodeIds?.forEach((nodeId: any) => {
    const node = workflowStore.state.nodes.find((n: any) => n.id === nodeId);
    if (node && isNodeFullyContained(node, props.group)) {
      containedNodesInitialPositions.value.set(nodeId, { ...node.position });
      affectedNodeIds.value.add(nodeId);
    }
  });
  
  recursionGroup(props.group);
  
  // 提前获取受影响的连接线
  affectedConnections.value = workflowStore.state.connections.filter((conn: { sourcePortId: string; targetPortId: string; }) => {
    const sourceMatch = conn.sourcePortId.match(/(?:input|output)-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);
    const targetMatch = conn.targetPortId.match(/(?:input|output)-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);
    const sourceNodeId = sourceMatch ? sourceMatch[1] : '';
    const targetNodeId = targetMatch ? targetMatch[1] : '';
    return affectedNodeIds.value.has(sourceNodeId) || affectedNodeIds.value.has(targetNodeId);
  });
  
  isDragging.value = true;
  window.addEventListener('mousemove', handleMouseMove);
  window.addEventListener('mouseup', handleMouseUp);
};

// 修改递归处理组的函数
const recursionGroup = (curGroup: any) => {
  if (!curGroup) {
    return;
  }
  
  curGroup.containedGroups?.forEach((groupId: any) => {
    const group = workflowStore.state.groups.find((n: any) => n.id === groupId);
    
    if (!group || containedGroupsInitialPositions.value.has(group.id)) {
      return;
    }
    
    // 检查组是否完全包含在当前组内
    if (isNodeFullyContained(group, curGroup)) {
      containedGroupsInitialPositions.value.set(groupId, { ...group.position });
      affectedNodeIds.value.add(groupId);
      
      // 处理被包含组内的节点
      group.nodeIds?.forEach((nodeId: any) => {
        const node = workflowStore.state.nodes.find((n: any) => n.id === nodeId);
        if (node && isNodeFullyContained(node, group)) {
          containedNodesInitialPositions.value.set(nodeId, { ...node.position });
          affectedNodeIds.value.add(nodeId);
        }
      });
      
      // 递归处理子组
      recursionGroup(group);
    }
  });
};

const handleMouseMove = (e: MouseEvent) => {
  if (!isDragging.value) return;
  
  // 计算鼠标移动的距离
  const deltaX = (e.clientX - dragStartPos.value.x) / scale;
  const deltaY = (e.clientY - dragStartPos.value.y) / scale;
  
  // 更新位置
  const newPosition = {
    x: dragOffset.x + deltaX,
    y: dragOffset.y + deltaY
  };
  
  // 先更新当前组的位置
  props.group.position.x = newPosition.x;
  props.group.position.y = newPosition.y;
//  emit('update:position', props.group.id, newPosition);
  
  synchronizePositions(deltaX,deltaY);
  
  
  // 更新受影响节点的连接线
  if(!props.svgContainer) return;
  const svg = props.svgContainer;
  if (!svg) return;
  
  // 批量更新连接线
  workflowStore.batchUpdateConnections(updatedConnections(svg));
};

/**
 * 同步移动包含的节点，使用初始位置计算
 */
const synchronizePositions=(deltaX:number,deltaY:number)=>{
	containedNodesInitialPositions.value.forEach((initialPos, nodeId) => {
	  workflowStore.updateNodePosition(nodeId, {
	    x: initialPos.x + deltaX,
	    y: initialPos.y + deltaY
	  });
	});
	
	containedGroupsInitialPositions.value.forEach((initialPos, groupId) => {
	  workflowStore.updateGroupPosition(groupId, {
	    x: initialPos.x + deltaX,
	    y: initialPos.y + deltaY
	  });
	});
}

/**
 * 更新连接线
 */
const updatedConnections=(svg:SVGSVGElement)=>{
	return affectedConnections.value.map(conn => {
	  // 使用更精确的端口选择器
	  const sourcePort = document.getElementById(`${conn.sourcePortId}-sign`);
	  const targetPort = document.getElementById(`${conn.targetPortId}-sign`);
		
	  if (sourcePort && targetPort) {
	    const sourceRect = sourcePort.getBoundingClientRect();
	    const targetRect = targetPort.getBoundingClientRect();
	    
		const _data = workflowStore.getSvgTransform(svg);
		if(!_data)  return conn;
		scale = _data.scale;
	    const currentScale = _data.scale;
	    const currentTranslateX = _data.translateX;
	    const currentTranslateY = _data.translateY;
	    const currentSvgRect = svg.getBoundingClientRect();
	    
	    // 转换为 SVG 坐标
	    const sourcePoint = {
	      x: (sourceRect.left + sourceRect.width / 2 - currentSvgRect.left - currentTranslateX) / currentScale,
	      y: (sourceRect.top + sourceRect.height / 2 - currentSvgRect.top - currentTranslateY) / currentScale
	    };
	    
	    const targetPoint = {
	      x: (targetRect.left + targetRect.width / 2 - currentSvgRect.left - currentTranslateX) / currentScale,
	      y: (targetRect.top + targetRect.height / 2 - currentSvgRect.top - currentTranslateY) / currentScale
	    };
	    
	    // 计算控制点的偏移量
	    const dx = Math.abs(targetPoint.x - sourcePoint.x);
	    const controlOffset = Math.min(100, dx / 2);
	    
	    // 生成新的路径
	    const path = `M ${sourcePoint.x} ${sourcePoint.y} C ${sourcePoint.x + controlOffset} ${sourcePoint.y}, ${targetPoint.x - controlOffset} ${targetPoint.y}, ${targetPoint.x} ${targetPoint.y}`;
	    
	    return {
	      ...conn,
	      path
	    };
	  }
	  return conn;
	});
}

/**
 * 鼠标释放
 */
const handleMouseUp = () => {
	if (!isDragging.value) return;
	isDragging.value = false;
	 workflowStore.updateContainments();
	// 清理所有记录
	containedNodesInitialPositions.value.clear();
	containedGroupsInitialPositions.value.clear();
	affectedNodeIds.value.clear();
	affectedConnections.value = [];
	  
	window.removeEventListener('mousemove', handleMouseMove);
	window.removeEventListener('mouseup', handleMouseUp);
};

// 添加调整大小相关的状态
const isResizing = ref(false);
const resizeDirection = ref<'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | null>(null);
const startSize = ref({ width: 0, height: 0 });
const startPosition = ref({ x: 0, y: 0 });

// 添加当前宽度的响应式引用
const currentWidth = ref(props.group.size.width);

// 处理调整大小开始
const handleResizeStart = (e: MouseEvent, direction: 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w') => {
  e.stopPropagation();
  e.preventDefault();
  
  if(!props.svgContainer) return;
  const svg = props.svgContainer;
  if (!svg) return;
  
  const _data = workflowStore.getSvgTransform(svg);
  if(!_data)  return;
  scale = _data.scale;

  isResizing.value = true;
  resizeDirection.value = direction;
  
  // 保存初始大小和位置
  startSize.value = { ...props.group.size };
  startPosition.value = { ...props.group.position };
  
  // 保存鼠标起始位置
  dragStartPos.value = {
    x: e.clientX,
    y: e.clientY
  };
  
  window.addEventListener('mousemove', handleResizeMouseMove);
  window.addEventListener('mouseup', handleResizeMouseUp);
};

// 修改调整大小时的移动处理
const handleResizeMouseMove = (e: MouseEvent) => {
  if (!isResizing.value || !resizeDirection.value) return;
  
  // 计算鼠标移动的距离
  const deltaX = (e.clientX - dragStartPos.value.x) / scale;
  const deltaY = (e.clientY - dragStartPos.value.y) / scale;
  
  let newSize = { ...startSize.value };
  let newPosition = { ...startPosition.value };
  
  // 根据不同方向调整大小和位置
  switch (resizeDirection.value) {
    case 'nw':
      newSize.width = Math.max(100, startSize.value.width - deltaX);
      newSize.height = Math.max(100, startSize.value.height - deltaY);
      newPosition.x = startPosition.value.x + (startSize.value.width - newSize.width);
      newPosition.y = startPosition.value.y + (startSize.value.height - newSize.height);
      break;
    case 'n':
      newSize.height = Math.max(100, startSize.value.height - deltaY);
      newPosition.y = startPosition.value.y + (startSize.value.height - newSize.height);
      break;
    case 'ne':
      newSize.width = Math.max(100, startSize.value.width + deltaX);
      newSize.height = Math.max(100, startSize.value.height - deltaY);
      newPosition.y = startPosition.value.y + (startSize.value.height - newSize.height);
      break;
    case 'e':
      newSize.width = Math.max(100, startSize.value.width + deltaX);
      break;
    case 'se':
      newSize.width = Math.max(100, startSize.value.width + deltaX);
      newSize.height = Math.max(100, startSize.value.height + deltaY);
      break;
    case 's':
      newSize.height = Math.max(100, startSize.value.height + deltaY);
      break;
    case 'sw':
      newSize.width = Math.max(100, startSize.value.width - deltaX);
      newSize.height = Math.max(100, startSize.value.height + deltaY);
      newPosition.x = startPosition.value.x + (startSize.value.width - newSize.width);
      break;
    case 'w':
      newSize.width = Math.max(100, startSize.value.width - deltaX);
      newPosition.x = startPosition.value.x + (startSize.value.width - newSize.width);
      break;
  }
  
  // 立即更新当前宽度
  currentWidth.value = newSize.width;
  
  // 更新组的大小和位置
  props.group.size = newSize;
  props.group.position = newPosition;
  
  // 发出更新事件
  // emit('update:size', props.group.id, newSize);
  // emit('update:position', props.group.id, newPosition);
};

// 处理调整大小结束
const handleResizeMouseUp = () => {
  isResizing.value = false;
  resizeDirection.value = null;
  //更新包含关系
  workflowStore.updateContainments();
  window.removeEventListener('mousemove', handleResizeMouseMove);
  window.removeEventListener('mouseup', handleResizeMouseUp);
};

// 监听组大小变化
watch(() => props.group.size.width, (newWidth) => {
  currentWidth.value = newWidth;
});

// 处理边框调整大小
const handleResizeBorderMouseDown = (e: MouseEvent) => {
  // 阻止事件冒泡，防止触发拖拽
  e.stopPropagation();
  e.preventDefault();
  
  const rect = (e.target as SVGElement).getBoundingClientRect();
  const mouseX = e.clientX - rect.left;
  const mouseY = e.clientY - rect.top;
  
  // 确定调整方向
  const direction = getResizeDirection(mouseX, mouseY, rect);
  if (!direction) return;
  handleResizeStart(e, direction);
};

// 获取调整方向
const getResizeDirection = (mouseX: number, mouseY: number, rect: DOMRect) => {
  const threshold = 8; // 边缘检测阈值
  const isLeft = mouseX <= threshold;
  const isRight = mouseX >= rect.width - threshold;
  const isTop = mouseY <= threshold;
  const isBottom = mouseY >= rect.height - threshold;
  
  if (isLeft && isTop) return 'nw';
  if (isRight && isTop) return 'ne';
  if (isRight && isBottom) return 'se';
  if (isLeft && isBottom) return 'sw';
  if (isLeft) return 'w';
  if (isRight) return 'e';
  if (isTop) return 'n';
  if (isBottom) return 's';
  return null;
};

// 获取调整方向的鼠标样式
const getResizeCursor = (mouseX: number, mouseY: number, rect: DOMRect) => {
  const threshold = 8;
  const isLeft = mouseX <= threshold;
  const isRight = mouseX >= rect.width - threshold;
  const isTop = mouseY <= threshold;
  const isBottom = mouseY >= rect.height - threshold;
  
  if (isLeft && isTop) return 'nw-resize';
  if (isRight && isTop) return 'ne-resize';
  if (isRight && isBottom) return 'se-resize';
  if (isLeft && isBottom) return 'sw-resize';
  if (isLeft) return 'w-resize';
  if (isRight) return 'e-resize';
  if (isTop) return 'n-resize';
  if (isBottom) return 's-resize';
  return 'move';
};

// 修改边框鼠标移动事件
const handleResizeBorderMouseMove = (e: MouseEvent) => {
  const rect = (e.target as SVGElement).getBoundingClientRect();
  const mouseX = e.clientX - rect.left;
  const mouseY = e.clientY - rect.top;
  
  (e.target as SVGElement).style.cursor = getResizeCursor(mouseX, mouseY, rect);
};


const handleRename=()=>{
	ElMessageBox.prompt('请输入组名称', '重命名', {
		confirmButtonText: '确定',
		cancelButtonText: '取消',
		inputPattern: /^\S+$/, // 或者使用 /^.+$/ 如果允许空格
		inputErrorMessage: '请输入正确的名称',
	})
	.then(({ value }) => {
	 //  ElMessage({
		// type: 'success',
		// message: `Your email is:${value}`,
	 //  })
	  props.group.title=value
	})
	.catch(() => {
	  ElMessage({
		type: 'info',
		message: '已取消',
	  })
	})
}

</script>

<style lang="scss" scoped>
.workflow-group-node {
  &.selected {
    .group-background {
      filter: drop-shadow(0 0 4px rgba(64, 158, 255, 0.4));
    }
  }
  
  .group-header {
    cursor: move; // 修改为 move
    user-select: none;
    transition: none;
    
    &:active {
      cursor: move; // 修改为 move
    }
    
    path {
      transition: none;
    }
  }
  
  &.dragging {
    .group-header {
      z-index: 1000000000000;  // 确保拖拽时在最上层
    }
  }
  
  .resize-border {
    pointer-events: all;
    
    &:hover {
      stroke: #66b1ff;
      stroke-width: 2;
    }
  }
  
  &.resizing {
    .resize-border {
      cursor: inherit; // 保持调整时的鼠标样式
    }
  }
}
</style>